package com.haidechizi.i18n.common.executor;

import com.haidechizi.i18n.common.api.vo.SingleLanguage;
import com.haidechizi.i18n.common.cache.CacheService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * cache Executor 提供缓存的功能
 */
public class CacheExecutor implements Executor {

    private Executor executor;

    private CacheService cacheService;

    private int i18nUseCacheExpireTime;

    public CacheExecutor(Executor executor, CacheService cacheService, int i18nUseCacheExpireTime) {
        this.executor = executor;
        this.cacheService = cacheService;
        this.i18nUseCacheExpireTime = i18nUseCacheExpireTime;
    }

    @Override
    public List<SingleLanguage> queryLocaleInfo(String systemCode, String businessCode, String languageName,
                                                List<String> businessKeyList) {
        return queryForCache(systemCode, businessCode, languageName, businessKeyList);
    }

    /**
     * 设置缓存
     *
     * @param systemCode
     * @param businessCode
     * @param languageName
     * @param singleLanguageList
     */
    private void setI18nCache(String systemCode, String businessCode, String languageName,
                              List<SingleLanguage> singleLanguageList, int i18nUseCacheExpireTime) {
        cacheService.setCache(systemCode, businessCode, languageName, singleLanguageList, i18nUseCacheExpireTime);
    }

    /**
     * 查询缓存
     *
     * @param systemCode
     * @param businessCode
     * @param languageName
     * @param businessKeyList
     * @return
     */
    private List<SingleLanguage> queryForCache(String systemCode, String businessCode, String languageName,
                                               List<String> businessKeyList) {
        List<SingleLanguage> cacheLanguageList = cacheService.getCache(systemCode, businessCode, languageName,
                businessKeyList);
        List<String> cacheKeyList = new ArrayList<>();

        Iterator<SingleLanguage> iterator = cacheLanguageList.iterator();
        while (iterator.hasNext()) {
            SingleLanguage singleLanguage = iterator.next();
            cacheKeyList.add(singleLanguage.getBusinessKey());
            if ("&".equals(singleLanguage.getDocJson()) || StringUtils.isBlank(singleLanguage.getDocJson())) {
                iterator.remove();
            }
        }

        businessKeyList.removeAll(cacheKeyList);
        if (CollectionUtils.isEmpty(businessKeyList)) {
            return cacheLanguageList;
        }

        // 部分key未命中缓存
        List<SingleLanguage> languageList = executor.queryLocaleInfo(systemCode, businessCode, languageName,
                businessKeyList);

        cacheLanguageList.addAll(languageList);
        // 设置缓存
        setI18nCache(systemCode, businessCode, languageName, languageList, i18nUseCacheExpireTime);

        List<String> existKeys =
                languageList.stream().map(singleLanguage -> singleLanguage.getBusinessKey()).collect(Collectors.toList());

        businessKeyList.removeAll(existKeys);

        if (CollectionUtils.isNotEmpty(businessKeyList)) {
            List<SingleLanguage> notExistList = new ArrayList<>();
            businessKeyList.forEach(businessKey -> {
                SingleLanguage singleLanguage = new SingleLanguage();
                singleLanguage.setBusinessKey(businessKey);
                singleLanguage.setDocJson("&");
                notExistList.add(singleLanguage);
            });
            // 设置缓存
            setI18nCache(systemCode, businessCode, languageName, notExistList, i18nUseCacheExpireTime);
        }
        return cacheLanguageList;
    }
}
